package top.luoyuanxiang.mqtt.utils;


import java.nio.charset.StandardCharsets;
import java.util.Base64;

public class Jtt808Utils {
    private static final Base64.Encoder encoder = Base64.getEncoder();
    private static final Base64.Decoder decoder = Base64.getDecoder();

    /**
     * 字符串转二进制
     *
     * @param str hex字符串
     * @return byte[]
     */
    public static byte[] hex2byte(String str) {
        if (str == null) {
            return null;
        }
        str = str.trim();
        int len = str.length();
        if (len == 0 || len % 2 == 1) {
            return null;
        }
        byte[] b = new byte[len / 2];
        try {
            for (int i = 0; i < str.length(); i += 2) {
                b[i / 2] = (byte) Integer.decode("0x" + str.substring(i, i + 2)).intValue();
            }
            return b;
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * ASCII 转字符串
     *
     * @param value 价值
     * @return {@link String}
     */
    public static String asciiToString(String value) {
        StringBuilder sbu = new StringBuilder();
        String[] chars = value.split(",");
        for (String aChar : chars) {
            sbu.append((char) Integer.parseInt(aChar));
        }
        return sbu.toString();
    }

    /**
     * 字符串转为ASCII
     *
     * @param value 价值
     * @return {@link String}
     */
    public static String stringToAscii(String value) {
        StringBuilder sbu = new StringBuilder();
        char[] chars = value.toCharArray();
        for (int i = 0; i < chars.length; i++) {
            if (i != chars.length - 1) {
                sbu.append((int) chars[i]).append(",");
            } else {
                sbu.append((int) chars[i]);
            }
        }
        return sbu.toString();
    }

    /**
     * byte 到 ascstring
     *
     * @param bArray B阵列
     * @return {@link String}
     */
    public static String byteToASCString(byte[] bArray) {
        StringBuilder strASC = new StringBuilder();
        String strTemp;
        for (byte b : bArray) {
            strTemp = String.format("%c", b);
            strASC.append(strTemp);
        }
        return strASC.toString();
    }

    /**
     * BASE64 编码
     *
     * @param buff byte[]
     * @return str
     */
    public static String encodeBufferBase64(byte[] buff) {
        return buff == null ? null : new String(encoder.encode(buff), StandardCharsets.UTF_8);
    }

    /**
     * BASE64解码
     *
     * @param s str
     * @return byte[]
     */
    public static byte[] decodeBufferBase64(String s) {
        return s == null ? null : decoder.decode(s);
    }

    /**
     * BASE64 字节数组编码
     *
     * @param s byte[]
     * @return String
     */
    public static String encodeBase64(byte[] s) {
        if (s == null) {
            return null;
        }
        String res = new String(encoder.encode(s), StandardCharsets.UTF_8);
        res = res.replace("\n", "");
        res = res.replace("\r", "");
        return res;
    }

    /**
     * BASE64解码
     *
     * @param buff byte[]
     * @return byte[]
     */
    public static byte[] decodeBase64(byte[] buff) {
        if (buff == null) {
            return null;
        }
        return decoder.decode(buff);
    }

    /**
     * 从字节中获取 EIGTH 位字符串
     *
     * @param b b
     * @return {@link String}
     */
    public static String getEigthBitsStringFromByte(int b) {
        b |= 256; // mark the 9th digit as 1 to make sure the string
        String str = Integer.toBinaryString(b);
        int len = str.length();
        return str.substring(len - 8, len);
    }

    /**
     * 从 EIGTH 位字符串中获取字节
     *
     * @param str str
     * @return byte
     */
    public static byte getByteFromEigthBitsString(String str) {
        byte b;
        if (str.charAt(0) == '1') {
            str = "0" + str.substring(1);
            b = Byte.valueOf(str, 2);
            b |= (byte) 128;
        } else {
            b = Byte.valueOf(str, 2);
        }
        return b;
    }

    /**
     * 将一个16字节数组转成128二进制数组
     *
     * @param b byte[]
     * @return boolean[]
     */
    public static boolean[] getBinaryFromByte(byte[] b) {
        boolean[] binary = new boolean[b.length * 8 + 1];
        StringBuilder strsum = new StringBuilder();
        for (byte value : b) {
            strsum.append(getEigthBitsStringFromByte(value));
        }
        for (int i = 0; i < strsum.length(); i++) {
            binary[i + 1] = strsum.substring(i, i + 1).equalsIgnoreCase("1");
        }
        return binary;
    }

    /**
     * 将一个128二进制数组转成16字节数组
     *
     * @param binary boolean[]
     * @return byte
     */
    public static byte[] getByteFromBinary(boolean[] binary) {

        int num = (binary.length - 1) / 8;
        if ((binary.length - 1) % 8 != 0) {
            num = num + 1;
        }
        byte[] b = new byte[num];
        StringBuilder s = new StringBuilder();
        for (int i = 1; i < binary.length; i++) {
            if (binary[i]) {
                s.append("1");
            } else {
                s.append("0");
            }
        }
        String tmpstr;
        int j = 0;
        for (int i = 0; i < s.length(); i = i + 8) {
            tmpstr = s.substring(i, i + 8);
            b[j] = getByteFromEigthBitsString(tmpstr);
            j = j + 1;
        }
        return b;
    }

    /**
     * 将一个byte位图转成字符串
     *
     * @param b byte[]
     * @return str
     */
    public static String getStrFromBitMap(byte[] b) {
        StringBuilder strsum = new StringBuilder();
        for (byte value : b) {
            strsum.append(getEigthBitsStringFromByte(value));
        }
        return strsum.toString();
    }

    /**
     * bytes转换成十六进制字符串,大写返回
     *
     * @param b 字节
     * @return 字符串
     */
    public static String byte2HexToUpperCase(byte[] b) {
        return byte2Hex(b).toUpperCase();
    }

    /**
     * Byte2 十六进制
     *
     * @param b b
     * @return {@link String}
     */
    public static String byte2Hex(byte[] b) {
        StringBuilder hs = new StringBuilder();
        String stmp;
        for (byte value : b) {
            stmp = (Integer.toHexString(value & 0XFF));
            if (stmp.length() == 1) {
                hs.append("0").append(stmp);
            } else {
                hs.append(stmp);
            }
        }
        return hs.toString();
    }

    /**
     * 将16进制字符串转成bcd码
     *
     * @param hexStr 16进制字符串
     * @return byte
     */
    public static byte[] hexStr2BCDBytes(String hexStr) {
        if (hexStr.length() % 2 == 1) {
            hexStr = "0" + hexStr;
        }
        return hex2byte(hexStr);
    }


    /**
     * 将BCD码转成16进制字符串
     *
     * @param bcdBytes byte
     * @return str
     */
    public static String bcdBytes2HexStr(byte[] bcdBytes) {
        return byte2Hex(bcdBytes);
    }

    /**
     * 将long转成BCD码
     *
     * @param num 10进制
     * @return byte
     */
    public static byte[] long2BCDBytes(long num) {
        String aHex = Long.toHexString(num);
        return hexStr2BCDBytes(aHex);
    }

    /**
     * 将int转成BCD码
     *
     * @param num int
     * @return byte
     */
    public static byte[] int2BCDBytes(int num) {
        String aHex = Integer.toHexString(num);
        return hexStr2BCDBytes(aHex);
    }

    /**
     * bcd码转为long(10进制)
     *
     * @param bcdBytes byte
     * @return long
     */
    public static long bcdBytes2Long(byte[] bcdBytes) {
        String aHex = bcdBytes2HexStr(bcdBytes);
        return Long.parseLong(aHex, 16);
    }


    /**
     * bcd码转为int(10进制)
     *
     * @param bcdBytes byte
     * @return int
     */
    public static int bcdBytes2Int(byte[] bcdBytes) {
        String aHex = bcdBytes2HexStr(bcdBytes);
        return Integer.parseInt(aHex, 16);
    }

    /**
     * 将byte数组bRefArr转为一个整数,字节数组的低位是整型的低字节位
     *
     * @param bRefArr byte
     * @return int
     */
    public static int byteToInt(byte[] bRefArr) {
        int iOutcome = 0;
        byte bLoop;

        for (int i = 0; i < bRefArr.length; i++) {
            bLoop = bRefArr[i];
            iOutcome += (bLoop & 0xFF) << (8 * i);
        }
        return iOutcome;
    }

    /**
     * 位图十六进制二进制
     *
     * @param bitmap 位图
     * @return {@link String}
     */
    public static String bitmapHex2Binary(String bitmap) {
        if (bitmap == null || bitmap.length() % 2 != 0) {
            return null;
        }
        StringBuilder bString = new StringBuilder();
        String tmp;
        for (int i = 0; i < bitmap.length(); i++) {
            tmp = "0000"
                    + Integer.toBinaryString(Integer.parseInt(bitmap
                    .substring(i, i + 1), 16));
            bString.append(tmp.substring(tmp.length() - 4));
        }
        return bString.toString();
    }

    /**
     * 位图二进制转十六进制
     *
     * @param bitmap 位图
     * @return {@link String}
     */
    public static String binary2Hex(String bitmap) {
        return Integer.toHexString(Integer.parseInt(bitmap, 2));
    }

    /**
     * 位图十六进制转二进制
     *
     * @param hexStr 位图
     * @return {@link String}
     */
    public static String hex2Binary(String hexStr) {
        return Integer.toBinaryString(Integer.parseInt(hexStr, 16));
    }

    /**
     * 获取位图str
     *
     * @param str8583 STR8583系列
     * @return {@link String}
     */
    public static String getBitMapStr(String str8583) {
        return str8583.substring(30, 46);
    }
}
